package com.zx1316.javadoudizhuserver;

import javafx.scene.control.Alert;

import java.io.IOException;
import java.net.BindException;
import java.net.Inet4Address;
import java.net.ServerSocket;
import java.net.UnknownHostException;

public class Server {
    private static final ClientThread[] CLIENTS = new ClientThread[3];
    private final Controller controller;
    private final GameThread gameThread;
    private final Object lock = new Object();
    private final int totalRounds;
    private final boolean hasTips;
    private final boolean allowDouble;
    private ServerThread serverThread;
    private boolean isStart;

    public Server(int totalRounds, boolean hasTips, boolean allowDouble, Controller controller) {
        this.totalRounds = totalRounds;
        this.hasTips = hasTips;
        this.allowDouble = allowDouble;
        this.controller = controller;
        gameThread = new GameThread(this, controller, lock);
        gameThread.setDaemon(true);
        gameThread.start();
    }

    public static synchronized ClientThread[] getClients() {
        return CLIENTS;
    }

    public void stopServer(boolean forced) {
        try {
            for (int i = 0; i < 3; i++) {
                if (CLIENTS[i] != null) {
                    CLIENTS[i].getWriter().println("CLOSE");
                    CLIENTS[i].getWriter().flush();
                    CLIENTS[i].getSocket().close();
                }
            }
            if (forced) {
                gameThread.stop();
            }
            serverThread.getServerSocket().close();
            isStart = false;
        } catch (IOException e) {
            e.printStackTrace();
            isStart = true;
        }
    }

    public void startServer(String hostName, int port, String password) {
        try {
            ServerSocket serverSocket = new ServerSocket(port, 50, Inet4Address.getByName(hostName));
            serverThread = new ServerThread(this, serverSocket, password, lock, gameThread, controller);
            serverThread.setDaemon(true);
            serverThread.start();
            isStart = true;
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("端口号超出范围！");
            alert.showAndWait();
        } catch (BindException e) {
            e.printStackTrace();
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("端口被占用或主机名错误！");
            alert.showAndWait();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setHeaderText("主机名错误！");
            alert.showAndWait();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isStart() {
        return isStart;
    }

    public int getTotalRounds() {
        return totalRounds;
    }

    public boolean isHasTips() {
        return hasTips;
    }

    public boolean isAllowDouble() {
        return allowDouble;
    }
}
